1   /*
2    * Copyright (C) 2007 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect.testing.testers;
18  
19  import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
20  import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
21  import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
22  import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_ADD_WITH_INDEX;
23  import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_SET;
24  import static com.google.common.collect.testing.testers.Platform.listListIteratorTesterNumIterations;
25  import static java.util.Collections.singleton;
26  
27  import com.google.common.annotations.GwtCompatible;
28  import com.google.common.annotations.GwtIncompatible;
29  import com.google.common.collect.testing.Helpers;
30  import com.google.common.collect.testing.IteratorFeature;
31  import com.google.common.collect.testing.ListIteratorTester;
32  import com.google.common.collect.testing.features.CollectionFeature;
33  import com.google.common.collect.testing.features.ListFeature;
34  
35  import java.lang.reflect.Method;
36  import java.util.List;
37  import java.util.ListIterator;
38  import java.util.Set;
39  import java.util.concurrent.CopyOnWriteArraySet;
40  
41  /**
42   * A generic JUnit test which tests {@code listIterator} operations on a list.
43   * Can't be invoked directly; please see
44   * {@link com.google.common.collect.testing.ListTestSuiteBuilder}.
45   *
46   * @author Chris Povirk
47   * @author Kevin Bourrillion
48   */
49  @GwtCompatible(emulated = true)
50  public class ListListIteratorTester<E> extends AbstractListTester<E> {
51    // TODO: switch to DerivedIteratorTestSuiteBuilder
52  
53    @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
54    @ListFeature.Require(absent = {SUPPORTS_SET, SUPPORTS_ADD_WITH_INDEX})
55    public void testListIterator_unmodifiable() {
56      runListIteratorTest(UNMODIFIABLE);
57    }
58  
59    /*
60     * For now, we don't cope with testing this when the list supports only some
61     * modification operations.
62     */
63    @CollectionFeature.Require(SUPPORTS_REMOVE)
64    @ListFeature.Require({SUPPORTS_SET, SUPPORTS_ADD_WITH_INDEX})
65    public void testListIterator_fullyModifiable() {
66      runListIteratorTest(MODIFIABLE);
67    }
68  
69    private void runListIteratorTest(Set<IteratorFeature> features) {
70      new ListIteratorTester<E>(
71          listListIteratorTesterNumIterations(), singleton(samples.e4), features,
72          Helpers.copyToList(getOrderedElements()), 0) {
73        {
74          // TODO: don't set this universally
75          stopTestingWhenAddThrowsException();
76        }
77  
78        @Override protected ListIterator<E> newTargetIterator() {
79          resetCollection();
80          return getList().listIterator();
81        }
82  
83        @Override protected void verify(List<E> elements) {
84          expectContents(elements);
85        }
86      }.test();
87    }
88  
89    public void testListIterator_tooLow() {
90      try {
91        getList().listIterator(-1);
92        fail();
93      } catch (IndexOutOfBoundsException expected) {
94      }
95    }
96  
97    public void testListIterator_tooHigh() {
98      try {
99        getList().listIterator(getNumElements() + 1);
100       fail();
101     } catch (IndexOutOfBoundsException expected) {
102     }
103   }
104 
105   public void testListIterator_atSize() {
106     getList().listIterator(getNumElements());
107     // TODO: run the iterator through ListIteratorTester
108   }
109 
110   /**
111    * Returns the {@link Method} instance for
112    * {@link #testListIterator_fullyModifiable()} so that tests of
113    * {@link CopyOnWriteArraySet} can suppress it with
114    * {@code FeatureSpecificTestSuiteBuilder.suppressing()} until <a
115    * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6570575">Sun bug
116    * 6570575</a> is fixed.
117    */
118   @GwtIncompatible("reflection")
119   public static Method getListIteratorFullyModifiableMethod() {
120     return Helpers.getMethod(
121         ListListIteratorTester.class, "testListIterator_fullyModifiable");
122   }
123 
124   /**
125    * Returns the {@link Method} instance for
126    * {@link #testListIterator_unmodifiable()} so that it can be suppressed in
127    * GWT tests.
128    */
129   @GwtIncompatible("reflection")
130   public static Method getListIteratorUnmodifiableMethod() {
131     return Helpers.getMethod(
132         ListListIteratorTester.class, "testListIterator_unmodifiable");
133   }
134 }